/**
* @file drv_usart1.c
* @brief usart1 interface
* @details 
* @author huangbin
* @version V1.0.0
* @date 2025-04-20
* @copyright All documents are copyrighted by Shenzhen Xinlongwei Technology Co., LTD.
*            They may not be used for commercial purposes without permission
*/
#include "inc.h"

#define __this_uart		USART1
#define DebugUartIrq	USART1_IRQn
#define UART_RX_MAX     USART1_RX_MAX
#define UART_TX_MAX     USART1_TX_MAX

USART1_t	DebugUart;

void usart1_init(UART_COPY_DATA fnCopy)
{
	NVIC_InitTypeDef NVIC_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
//    PA11 (USART1_TX),   PA10 (USART1_RX)
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 
	GPIO_Init(GPIOA, &GPIO_InitStructure);  

	USART_DeInit(__this_uart);

	USART_InitStructure.USART_BaudRate = 460800;//230400;//115200;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	USART_Init(__this_uart, &USART_InitStructure);
	
/* Enable the UART Interrupt Channel */
	NVIC_InitStructure.NVIC_IRQChannel = DebugUartIrq;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
    
    __this_uart->CR4 |= 0x02; //disable fifo,MH22D3芯片增加了fifo,但是默认是打开的
	USART_Cmd(__this_uart, ENABLE);
	DebugUart.RxCnt = 0;
	DebugUart.fnCopy = fnCopy;
	USART_ITConfig(__this_uart,USART_IT_TXE,DISABLE); //开始不能enalbe，否则TXE和TC中断会不停的来
	USART_ITConfig(__this_uart,USART_IT_RXNE,ENABLE);
    DebugPrintf("[UART] uart1 init ok\r\n");
  
}
//阻塞方式发送数据
void uart1_send_loop(const uint8_t* txBuf, uint32_t txLen)
{
  while(txLen--)
  {
	  while(!USART_GetFlagStatus(__this_uart,USART_FLAG_TC)) __NOP();
      USART_SendData(__this_uart, (uint8_t) *txBuf++);
  }
  while((__this_uart->SR & USART_FLAG_TC) == RESET) __NOP();
}
//中断方式发送数据
void uart1_send_interrupt(uint8_t* txBuf, uint16_t txLen)
{
	if(txLen > UART_TX_MAX)
		return;
	memcpy(DebugUart.TxBuf,txBuf,txLen);
	DebugUart.TxCnt = 0;
	DebugUart.TxTotal = txLen;
	USART_ITConfig(__this_uart, USART_IT_TXE, ENABLE);
}
//接收完一帧数据
static void UartRxTimeout(void)
{
    if(DebugUart.fnCopy)
        DebugUart.fnCopy(DebugUart.RxBuf,DebugUart.RxCnt);
	DebugUart.RxCnt = 0;	//1.接收正确，等下一帧。2.接收错误，超时等情况，恢复接收
} 
void USART1_IRQHandler(void)
{
 volatile uint8_t rbyte;

    if(USART_GetITStatus(__this_uart,USART_IT_RXNE) != RESET)
    {
      USART_ClearITPendingBit(__this_uart,USART_IT_RXNE);
        
        rbyte = __this_uart->DR & 0x00FF;
        if(DebugUart.RxCnt == 0)
        {
            TimeOutEnable(MCU_UART1_USE,MCU_UART1_TIMEOUT_MS,UartRxTimeout);	//帧超时，115200=0.868ms
        }
        if(DebugUart.RxCnt < UART_RX_MAX)
        {
            DebugUart.RxBuf[DebugUart.RxCnt++] = rbyte;		//先放起来
            TimeOutReset(MCU_UART1_USE); 		//这里要重置计数器，帧超时时间要设置得更短，才能快速响应
        }
    }
    else if(USART_GetITStatus(__this_uart,USART_IT_TXE) != RESET)
    {
        USART_ClearITPendingBit(__this_uart,USART_IT_TXE);
        if(DebugUart.TxCnt < DebugUart.TxTotal)
            __this_uart->DR = DebugUart.TxBuf[DebugUart.TxCnt++];
        else
        {
            USART_ITConfig(__this_uart,USART_IT_TXE,DISABLE);
        }
    }	
    else if(USART_GetFlagStatus(__this_uart,USART_FLAG_ORE) != RESET)
    {
        volatile uint8_t t = __this_uart->DR;
        USART_ClearFlag(__this_uart, USART_FLAG_ORE);
    }    
}
